home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / pd mix ii / sprite ed / spriteclock / sclock.s < prev    next >
Text File  |  1994-05-20  |  17KB  |  550 lines

  1. * Sprite Clock
  2. *
  3. *  This is a very simple clock that uses a sprite as it's display  medium.
  4. * It displays the time every minute for a couple seconds and then the sprite
  5. * disappears. The time is displayed in 12-hr. format; you'll have to figure
  6. * out if it is AM or PM yourself. 
  7. *  It is useful if you are working on different screens alot since a sprite
  8. * will appear in front of any screen.
  9. *  I had to design the numbers myself and I used alot of tricks to compress
  10. * the space their data would have taken so that the clock will remain small.
  11. * I would think that there is some way to take advantage of the fonts already
  12. * in the system but I did not know enough about the form of the font in 
  13. * memory and how to access that data so that it could be used.
  14. *  Alot of different techniques are used in order to load the numerals into
  15. * memory and I would think they would prove educational to someone.
  16.  
  17. * At this time this clock can not be terminated once it is started.
  18. * I don't mind this since it takes up very little memory. This program
  19. * could be given another port and a close message could be sent to it by
  20. * another program or by something like the workbench menus if they where
  21. * properly altered.
  22.  
  23. * Code size:         820 bytes
  24. * minumum stack:    1600 bytes
  25. * Running size:        6312 bytes
  26.  
  27. * I do not think it will work from the workbench in it's current version.
  28.  
  29. * Darrel Schneider
  30. ************************************************************************
  31.  
  32.           NOPAGE
  33.           NOLIST
  34.           LLEN 132
  35.  
  36. ;          INCLUDE "exec/types.i"
  37. ;          INCLUDE "exec/ables.i"
  38. ;          INCLUDE "exec/memory.i"
  39. ;          INCLUDE "devices/timer.i"
  40.  
  41. * the following equates take the place of the info in the above files
  42.  
  43.           MP_SIZE: EQU $22
  44.           MP_SIGBIT: EQU $F
  45.           MEMF_CLEAR: EQU $10000
  46.           MEMF_PUBLIC: EQU $1
  47.           MEMF_CHIP: EQU $2
  48.           NT_MSGPORT: EQU $4
  49.           NT_MESSAGE: EQU $5
  50.           IOTV_SIZE: EQU $28
  51.           LN_TYPE: EQU $8
  52.           LN_NAME: EQU $A
  53.           IO_DEVICE: EQU $14
  54.           IO_UNIT: EQU $18
  55.           IO_COMMAND: EQU $1C
  56.           IO_SIZE: EQU $20
  57.           MN_REPLYPORT: EQU $E
  58.           TR_ADDREQUEST: EQU $9
  59.           TR_GETSYSTIME: EQU $A
  60.           UNIT_VBLANK: EQU $1
  61.           TV_SECS: EQU $0
  62.           TV_MICRO: EQU $4
  63.  
  64.           XREF _AbsExecBase
  65.  
  66.           XREF _LVOOpenLibrary
  67.           XREF _LVOCloseLibrary
  68.  
  69.           XREF _LVOAllocMem
  70.           XREF _LVOFreeMem
  71.  
  72.           XREF _LVOAllocSignal
  73.           XREF _LVOFreeSignal
  74.  
  75.           XREF _LVOAddPort
  76.           XREF _LVORemPort
  77.  
  78.           XREF _LVOOpenDevice
  79.           XREF _LVOCloseDevice
  80.  
  81.           XREF _LVODoIO
  82.           XREF _LVOSendIO
  83.           XREF _LVOWaitIO
  84.  
  85.           XREF _LVOFindTask
  86.  
  87.           XREF _LVOGetSprite
  88.           XREF _LVOChangeSprite
  89.           XREF _LVOMoveSprite
  90.           XREF _LVOFreeSprite
  91.  
  92.           LIST
  93.           Temp:               EQUR d2
  94.           LoopCount:          EQUR d2
  95.           Secs:               EQUR d3
  96.           Micros:             EQUR d4
  97.           AndMask:            EQUR d5
  98.           Timer_Port:         EQUR d6
  99.           GraphicsBase:       EQUR d7
  100.  
  101.           BufferPTR:          EQUR a2
  102.           SimpleSpritePTR:    EQUR a3
  103.           NewDataPTR:         EQUR a4
  104.           Time_ReqPTR:        EQUR a5
  105.  
  106. ********** open libraries ***********
  107.  
  108.           movea.l   _AbsExecBase,a6
  109.           lea       GraphicsName(pc),a1
  110.           moveq.l   #0,d0
  111.           jsr       _LVOOpenLibrary(a6)
  112.           tst.l     d0
  113.          bne.s      NOAbortOpenLibrary ;V
  114.           rts       ;quit
  115.          NOAbortOpenLibrary:
  116.           move.l    d0,GraphicsBase
  117.  
  118. ********** create timer port **********
  119.  
  120.           ;get a signal bit
  121.           moveq.l   #-1,d0
  122.           jsr       _LVOAllocSignal(a6)
  123.           move.l    d0,d2
  124.           bmi.l     AbortCreateTimer1    ; if -1 AllocSignal failed so abort
  125.  
  126.           ; alloc port structure
  127.           moveq.l   #MP_SIZE,d0
  128.           move.l    #(MEMF_CLEAR!MEMF_PUBLIC),d1
  129.           jsr       _LVOAllocMem(a6)
  130.           move.l   d0,Timer_Port
  131.         bne.s   skipAbortCode ;V  it was allocated so skip the abort code
  132.           ; AllocMem failed so clean up and then abort
  133.           move.l    d2,d0
  134.           jsr       _LVOFreeSignal(a6)
  135.           bra.l     AbortCreateTimer2    ; if 0 AllocMem failed so abort
  136.  
  137.         skipAbortCode:
  138.           ; fill port fields
  139.           move.l    Timer_Port,a2
  140.           addq.l    #8,a2                 ; a2 = &LN_TYPE
  141.           move.w    #((NT_MSGPORT<<8)+Priority),(a2)+
  142.           ; the last instruction does the next two
  143.           ;   move.b    #NT_MSGPORT,(a2)+     ; LN_TYPE
  144.           ;   move.b    #Priority,(a2)+       ; LN_PRI
  145.           lea       TimerPortName(pc),a1
  146.           move.l    a1,(a2)+                  ; LN_NAME gets &TimerPortName
  147.           ; this instruction is done by the next one since it is a move.w 
  148.           ;   clr.b     (a2)+                 ; #PA_SIGNAL -> MP_FLAGS
  149.           move.w    d2,(a2)+                  ; MP_SIGBIT
  150.           moveq.l   #0,d0
  151.           movea.l   d0,a1
  152.           jsr       _LVOFindTask(a6)
  153.           move.l    d0,(a2)               ; MP_SIGTASK
  154.           ; add the port
  155.           movea.l   Timer_Port,a1
  156.           jsr       _LVOAddPort(a6)
  157.  
  158.  bra.s   SkipAbortSection ;V
  159.  
  160. *******************************************************************************
  161. **************************  TERMINATION SECTION *****************************
  162.  
  163. AbortNewDataAlloc:
  164.           moveq.l   #0,d0
  165.           move.w    10(SimpleSpritePTR),d0
  166.           exg       a6,GraphicsBase
  167.           jsr       _LVOFreeSprite(a6)
  168.           exg       a6,GraphicsBase
  169. AbortGetSprite:
  170.           moveq.l   #IOTV_SIZE,d4
  171.           adda.l    d4,Time_ReqPTR
  172.           adda.l    d4,Time_ReqPTR
  173.           moveq.l   #1,d3
  174.        bra.s BEGINCloseDeviceLOOP ;V
  175. AbortOpenDevice:
  176.           subq.l    #1,d3
  177.       beq.s SKIPCloseDeviceLOOP ;V
  178.           moveq.l   #0,d3
  179.        BEGINCloseDeviceLOOP:
  180.           ; close timer device
  181.           suba.l    d4,Time_ReqPTR
  182.           lea       (Time_ReqPTR),a1
  183.           jsr       _LVOCloseDevice(a6)
  184.        dbra d3,BEGINCloseDeviceLOOP ;^
  185.  
  186.       SKIPCloseDeviceLOOP:
  187.           ; deallocate Time_Req structure
  188.           moveq.l   #-1,d3
  189.           movea.l   Time_ReqPTR,a1
  190.           moveq.l   #1,d0
  191.          DeallocateLOOP:
  192.           move.b    d3,LN_TYPE(Time_ReqPTR)
  193.           move.l    d3,IO_DEVICE(Time_ReqPTR)
  194.           move.l    d3,IO_UNIT(Time_ReqPTR)
  195.           adda.l    d4,Time_ReqPTR
  196.          dbra d0,DeallocateLOOP
  197.           moveq.l   #IOTV_SIZE*2,d0
  198.           jsr       _LVOFreeMem(a6)
  199.  
  200. AbortTime_ReqAlloc:
  201.           ; close timer port
  202.           movea.l   Timer_Port,a1
  203.           jsr       _LVORemPort(a6)
  204.           movea.l   Timer_Port,a2
  205.             ; d3 = -1
  206.           move.b    d3,LN_NAME(a2)
  207.           move.l    d3,(a2)            ; LH_HEAD
  208.           move.l    MP_SIGBIT(a2),d0
  209.           jsr       _LVOFreeSignal(a6)
  210.           movea.l   Timer_Port,a1
  211.           moveq.l   #MP_SIZE,d0
  212.           jsr       _LVOFreeMem(a6)
  213.  
  214. AbortCreateTimer2:
  215. AbortCreateTimer1:
  216.           move.l    GraphicsBase,a1
  217.           jsr       _LVOCloseLibrary(a6)
  218.  
  219.           moveq.l   #0,d0
  220.           rts
  221.  
  222. ********************* END OF TERMINATION SECTION ***************************
  223. ****************************************************************************
  224.  
  225.  SkipAbortSection:
  226.  
  227. ********** initialize timerequest struct ***********
  228.  
  229.           ;alloc timerequest structure
  230.           moveq.l   #IOTV_SIZE*2,d0
  231.           move.l    #(MEMF_CLEAR!MEMF_PUBLIC),d1
  232.           jsr       _LVOAllocMem(a6)
  233.           tst.l     d0
  234.           beq.s     AbortTime_ReqAlloc
  235.           movea.l   d0,Time_ReqPTR
  236.  
  237.           move.w    #((NT_MESSAGE<<8)+Priority),LN_TYPE(Time_ReqPTR)
  238.           ; The previous instruction actually does the next two.
  239.           ;    move.b    #NT_MESSAGE,LN_TYPE(Time_ReqPTR)
  240.           ;    move.b    #Priority,LN_PRI(Time_ReqPTR)
  241.           move.l    Timer_Port,MN_REPLYPORT(Time_ReqPTR)
  242.           ; cleared in the AllocMem call
  243.           ;         clr.w     IO_FLAGS(Time_ReqPTR)  ; this also zeros IO_ERROR
  244.           move.w    #TR_ADDREQUEST,IO_COMMAND(Time_ReqPTR)
  245.  
  246.           moveq.l   #IOTV_SIZE,d0
  247.           move.w    #((NT_MESSAGE<<8)+Priority),LN_TYPE(Time_ReqPTR,d0.w)
  248.           move.w    #TR_GETSYSTIME,IO_COMMAND(Time_ReqPTR,d0.w)
  249.  
  250.  
  251. ********** open vblank timer device **************
  252.  
  253.           moveq.l   #1,d3
  254.           moveq.l   #IOTV_SIZE,d4
  255.         OpenDeviceLOOP:
  256.           lea       TimerName(pc),a0
  257.           lea       (Time_ReqPTR),a1
  258.           moveq.l   #UNIT_VBLANK,d0
  259.           moveq.l   #0,d1
  260.           jsr       _LVOOpenDevice(a6)
  261.           tst.l     d0
  262.           bne.l     AbortOpenDevice
  263.           adda.l    d4,Time_ReqPTR
  264.         dbra    d3,OpenDeviceLOOP
  265.           sub.l     d4,Time_ReqPTR
  266.           sub.l     d4,Time_ReqPTR
  267.  
  268. ********** initialize the Sprite *******************
  269.  
  270.           lea       SimpleSprite(pc),SimpleSpritePTR
  271.           move.l    SimpleSpritePTR,a0
  272.           moveq.l   #-1,d0
  273.           exg       a6,GraphicsBase
  274.           jsr       _LVOGetSprite(a6)
  275.           exg       a6,GraphicsBase
  276.           tst.l     d0
  277.           bmi       AbortGetSprite
  278.  
  279.           move.w    #43,4(SimpleSpritePTR)
  280.           clr.l     6(SimpleSpritePTR)
  281.  
  282. ********** initialize newData structure used by the Sprite **********
  283.  
  284.           move.w    #newDataSIZE,d0
  285.           move.l    #(MEMF_CLEAR!MEMF_CHIP),d1
  286.           jsr       _LVOAllocMem(a6)
  287.           tst.l     d0
  288.           beq       AbortNewDataAlloc
  289.           movea.l   d0,NewDataPTR
  290.  
  291.           moveq.l   #(newDataSIZE/4)-3,d0
  292.           lea       4(NewDataPTR),a0
  293.           move.l    #term,d1
  294.         BEGINnewDataLOOP:
  295.           move.l    d1,(a0)+
  296.         dbra        d0,BEGINnewDataLOOP ;^
  297.           move.w    #colon,88(NewDataPTR)
  298.  
  299. ********** initialize program register variables *****************
  300.  
  301.           lea       buffer(pc),BufferPTR
  302.           moveq.l   #AndMaskVALUE,AndMask
  303.  
  304. ********************* main loop *******************
  305.  
  306.           bsr.s     GetSecsTillNextMin
  307.           cmpi.w    #5,Secs
  308.         bpl.s DisplayTime ;V
  309.         bra.s WaitTillNextMin ;V
  310.     RESTART:
  311.           bsr.s     GetSecsTillNextMin
  312.         DisplayTime:
  313.           bsr.s     LoadBuffer
  314.           bsr.s     GetSecsTillNextMin  ;only needs to get Secs & Micros
  315.         WaitTillNextMin:
  316.           move.w    Secs,2+IO_SIZE+TV_SECS(Time_ReqPTR)
  317.           move.l    Micros,IO_SIZE+TV_MICRO(Time_ReqPTR)
  318.           movea.l   Time_ReqPTR,a1
  319.           jsr       _LVODoIO(a6)
  320.     bra RESTART ;^
  321.  
  322. ***************************** SUBROUTINES **********************************
  323. GetSecsTillNextMin:
  324.           moveq.l   #SEC_PER_MIN-1,Secs
  325.           move.l    #MICRO_PER_SEC-1,Micros
  326.           ; get the current time
  327.           lea       IOTV_SIZE(Time_ReqPTR),a1
  328.           jsr       _LVODoIO(a6)
  329.  
  330.           ; calculate # of Secs. till next minute and put it in d0
  331.           move.l    IOTV_SIZE+IO_SIZE+TV_SECS(Time_ReqPTR),d0
  332.           sub.l     IOTV_SIZE+IO_SIZE+TV_MICRO(Time_ReqPTR),micros
  333.           ; moveq.l   #0,Temp  ; clear to zero meaning AM
  334.           divu      #SEC_PER_HALF,d0
  335.           ; lsr.b     #1,d0           ; test lsbit by shifting it into C bit
  336.       ; bcc.s     AM ;V
  337.           ; moveq.l   #12,Temp      ; make it 12 if PM
  338.       ; AM:
  339.           swap      d0              ; d0 = # of seconds in the half day
  340.           exg       d0,d1
  341.           moveq.l   #0,d0
  342.           move.w    d1,d0
  343.           divu      #SEC_PER_MIN,d0
  344.           ; swap      Temp
  345.           move.w    d0,Temp    ; save the minutes*hrs. in half day
  346.           swap      d0
  347.           sub.w     d0,Secs
  348.  
  349.           rts
  350.  
  351. **********************************************
  352. LoadBuffer:
  353.           ; BufferPTR = &buffer[0]
  354.           clr.l     (BufferPTR)
  355.           ; load buffer with the current time
  356.           moveq.l   #0,d0
  357.           move.w    Temp,d0        ; d0 has minutes*hrs. in half day
  358.           ; clr.w     Temp
  359.           ; swap      Temp
  360.           divu      #MIN_PER_HOUR,d0
  361.           moveq.l   #0,d1
  362.           add.w     d0,d1           ; prepare # of hours in half day
  363.  
  364.           divu      #10,d1
  365.           tst.l     d1
  366.         bne.s WasNot12 ;V
  367.           move.w    #$0102,(bufferPTR)+
  368.        bra.s  Load2and3 ;V
  369.         WasNot12:
  370.           tst.w     d1
  371.          bne.s WasNotZero ;V
  372.           BlankOffset: EQU $a
  373.           move.b    #BlankOffset,d1
  374.          WasNotZero:
  375.           move.b    d1,(BufferPTR)+ ; buffer[0]
  376.           swap      d1
  377.           move.b    d1,(BufferPTR)+ ; buffer[1]
  378.  
  379.        Load2and3:
  380.           swap      d0
  381.           ext.l     d0
  382.           divu      #10,d0
  383.           move.b    d0,(BufferPTR)+     ; buffer[2]
  384.           swap      d0
  385.           move.b    d0,(BufferPTR)+     ; buffer[3]
  386.  
  387.           ; BufferPTR= &buffer[3]+1
  388.  
  389.           ; Print Sprite
  390.           lea       num4(NewDataPTR),a1
  391.           bsr.s     LoadSpriteNumber
  392.           ; BufferPTR= &buffer[3]
  393.  
  394.           lea       num3(NewDataPTR),a1
  395.           bsr.s     LoadSpriteNumber
  396.           ; BufferPTR= &buffer[2]
  397.  
  398.           lea       num2(NewDataPTR),a1
  399.           bsr.s     LoadSpriteNumber
  400.           ; BufferPTR= &buffer[1]
  401.  
  402.           lea       num1(NewDataPTR),a1
  403.           bsr.s     LoadSpriteNumber
  404.           ; BufferPTR= &buffer[0]
  405.  
  406.           moveq.l   #0,d3
  407.  
  408.           move.l    d3,a0
  409.           move.l    SimpleSpritePTR,a1
  410.           move.l    a2,-(sp)
  411.           movea.l   NewDataPTR,a2
  412.           exg       a6,GraphicsBase
  413.           jsr       _LVOChangeSprite(a6)
  414.  
  415.           move.l    d3,a0
  416.           move.l    SimpleSpritePTR,a1
  417.           move.l    #300,d0
  418.           moveq.l   #70,d1
  419.           jsr       _LVOMoveSprite(a6)
  420.  
  421.           move.w    #3,2+IO_SIZE+TV_SECS(Time_ReqPTR)  ; wait 3 Secs
  422.           ; clr.l     IO_SIZE+TV_MICRO(Time_ReqPTR)
  423.           exg       a6,GraphicsBase
  424.           lea       (Time_ReqPTR),a1
  425.           jsr       _LVODoIO(a6)
  426.           exg       a6,GraphicsBase
  427.  
  428.           moveq.l   #0,d0
  429.           move.l    #244,d1
  430.           move.l    d0,a0
  431.           move.l    SimpleSpritePTR,a1
  432.           jsr       _LVOMoveSprite(a6)
  433.           exg       a6,GraphicsBase
  434.  
  435.           move.l    (sp)+,a2
  436.  
  437.           rts
  438.  
  439. ******************** LoadSpriteNumber ************************
  440. ; loads the image of the number in -(BufferPTR)
  441. ; into the memory whose first long has the address in A1.
  442.  
  443. LoadSpriteNumber:
  444.           moveq.l   #0,d0
  445.           move.b    -(BufferPTR),d0
  446.           asl.b     #2,d0   ; multiply by 4
  447.           move.l    recipeTABLE(pc,d0.w),d1
  448.  
  449.           moveq.l   #7,LoopCount
  450.         BEGINdecodeRecipeLOOP:
  451.           move.l    d1,d0
  452.           and.w     AndMask,d0
  453.           move.b    imageTABLE(pc,d0.w),d0
  454.           lsl.w     #4,d0
  455.           move.w    d0,(a1)+
  456.           addq.l    #2,a1
  457.           lsr.l     #4,d1  ; get next 4-bit incoded image
  458.         dbra      LoopCount,BEGINdecodeRecipeLOOP ;^
  459.  
  460.           rts
  461.  
  462.         imageTABLE:
  463.           DC.B twoDots
  464.           DC.B Dot1
  465.           DC.B Dot2
  466.           DC.B blank
  467.           DC.B Dot4
  468.           DC.B Dot5
  469.           DC.B Dot6
  470.           DC.B Dot7
  471.           DC.B Dot8
  472.           DC.B bar
  473.           DC.B lBar
  474.           DC.B rBar
  475.           DC.B sBar
  476.           DC.B triple
  477.           DC.B fours2Dot
  478.           DC.B onesBigDot
  479.  
  480.         recipeTABLE:          CNOP 0,2
  481.           zero:     DC.L $c000000c
  482.           one:      DC.L $d44444f4
  483.           two:      DC.L $b111c88c
  484.           three:    DC.L $a888c88a
  485.           four:     DC.L $7779eee7
  486.           five:     DC.L $c088a119
  487.           six:      DC.L $c00a112f
  488.           seven:    DC.L $5556788b
  489.           eight:    DC.L $c000c00c
  490.           nine:     DC.L $6788b00c
  491.           space:    DC.L $33333333
  492.  
  493.  
  494. ***********************************************************************
  495. *    SECTION "initialized data",DATA
  496.  
  497.           twoDots:    EQU $81
  498.           Dot1:       EQU $80
  499.           Dot2:       EQU $40
  500.           blank:      EQU $00
  501.           Dot4:       EQU $10
  502.           Dot5:       EQU $08
  503.           Dot6:       EQU $04
  504.           Dot7:       EQU $02
  505.           Dot8:       EQU $01
  506.           bar:        EQU $ff
  507.           lBar:       EQU $fe
  508.           rBar:       EQU $7f
  509.           sBar:       EQU $7e
  510.           triple:     EQU $38
  511.           fours2Dot:  EQU $82
  512.           onesBigDot: EQU $30
  513.  
  514.           colon:    EQU $0440
  515.           term:     EQU $7ffe
  516.           line:     EQU $00
  517.  
  518.  
  519.           AndMaskVALUE:     EQU $f
  520.  
  521.           TimerPortName:      CNOP 0,2
  522.                     DC.B 'timer',0
  523.           Priority: EQU 0
  524.           TimerName:          CNOP 0,2
  525.                     DC.B 'timer.device',0
  526.           GraphicsName:       CNOP 0,2
  527.                     DC.B 'graphics.library',0
  528.  
  529.           MICRO_PER_SEC:    EQU 1000000
  530.           SEC_PER_MIN:      EQU 60
  531.           MIN_PER_HOUR:     EQU 60
  532.           SEC_PER_HOUR:     EQU (60*60)
  533.           SEC_PER_HALF:     EQU (60*60*12)
  534.           SEC_PER_DAY:      EQU (60*60*24)
  535.           HOUR_PER_DAY:     EQU 24
  536.  
  537.           newDataSIZE:      EQU 196-16
  538.           ; newData offsets
  539.               num1:         EQU 12
  540.               num2:         EQU 52
  541.               num3:         EQU 96
  542.               num4:         EQU 136
  543.  
  544. *     SECTION "uninitialized data",BSS
  545.           buffer:             CNOP 0,2
  546.                     DS.B 4
  547.           SimpleSprite:       CNOP 0,2
  548.                     DS.W 6
  549.      END
  550.